package client.GUI;

import game.Player;
import game.client.Table;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import client.Client;

import server.Message;
import server.utils.CommandType;

public class Panel extends JPanel{
	private static final long serialVersionUID = 6567331137965825879L;
	private final int RIGID = 5;
	private final int ROWS = 2;
	private final int COLS = 5;
	private JTextField textField_Raise;
	private Table table;
	private Player player;
	private boolean turn;
	private Object turnLock = new Object();
	private JTextField textField_Chat;
	private Client client;
	private JTextArea textArea;
	private JLabel Free_Seat_3;
	private JLabel Free_Seat_2;
	private JLabel Free_Seat_4;
	private JLabel Free_Seat_1_me;
	private JLabel Seat1_kaart_1;
	private JLabel Seat1_kaart_2;
	private JLabel Seat2_kaart_1;
	private JLabel Seat2_kaart_2;
	private JLabel Seat3_kaart_1;
	private JLabel Seat3_kaart_2;
	private JLabel Seat4_kaart_1;
	private JLabel Seat4_kaart_2;
	private ArrayList<JLabel> seats;
	private ArrayList<JLabel> seatCards;
	private ArrayList<JLabel> tableCards;
	private ArrayList<JLabel> oppMoney;	
	private ArrayList<JButton> buttons;
	private JLabel tbl_Card_1;
	private JLabel tbl_Card_2;
	private JLabel tbl_Card_3;
	private JLabel tbl_Card_4;
	private JLabel tbl_Card_5;
	private JLabel lbl_TableBet;
	private JLabel lbl_mybettext;
	private JLabel lbl_MoneyLeft;
	private JLabel lbl_MyBet;
	private JLabel lbl_MoneyLeftText;
	private JLabel lbl_Seat4MoneyText;
	private JLabel lbl_Seat4Money;
	private JLabel lbl_Seat3MoneyText;
	private JLabel lbl_Seat3Money;
	private JLabel lbl_Seat2MoneyText;
	private JLabel lbl_Seat2Money;
	
	private Window window;
	private JPanel messagePanel;
	private JPanel myPanel;
	private JPanel infoPanel;
	private JPanel tablePanel;
	
	private GUIfuncs guiFuncs;
	/**
	 * Initializes game GUI.
	 * @param window JFrame where game is.
	 */
	public Panel(final Window window){
		this.window = window;
		turn = true;
		seats = new ArrayList<JLabel>();
		seatCards = new ArrayList<JLabel>();
		tableCards = new ArrayList<JLabel>();
		buttons = new ArrayList<JButton>();
		oppMoney = new ArrayList<JLabel>();
		
		this.setLayout(new BorderLayout());
		infoPanel = new JPanel();
		infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.Y_AXIS));
		JScrollPane scrollPane2 = new JScrollPane(infoPanel);
		scrollPane2.setVerticalScrollBarPolicy(
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		//Chat panel
		//=====================================================================
		Component box = Box.createRigidArea(new Dimension(RIGID, RIGID));
		this.messagePanel = new JPanel();
		//textarea
		textArea = new JTextArea(18, 10);
		textArea.setEditable(false);
		JScrollPane scrollPane = new JScrollPane(textArea);
		messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS));
		messagePanel.add(scrollPane);
		scrollPane.setVerticalScrollBarPolicy(
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		//textfield
		textField_Chat = new JTextField();
		textField_Chat.setMaximumSize(new Dimension(400, 20));
		textField_Chat.setColumns(10);
		messagePanel.add(textField_Chat);
		//msg button
		JButton btnSend = new JButton("Send message");
		btnSend.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				textArea.append(client.getName()+"> "+textField_Chat.getText()+"\n");
				client.sendMessage(new Message(player.getName(), CommandType.CHAT, textField_Chat.getText()));
				textField_Chat.setText("");
			}
		});
		messagePanel.add(btnSend);
		messagePanel.add(box);
		//QUIT button
		JButton btnQuit = new JButton("Quit");
		btnQuit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				setVisible(false);
				window.quit();
			}
		});
		messagePanel.add(btnQuit);
		
		this.add(messagePanel, BorderLayout.WEST);
		//=====================================================================
		//My info panel
		//=====================================================================
		this.myPanel = new JPanel();
		GridLayout grid = new GridLayout(ROWS, COLS, RIGID, RIGID);
		myPanel.setLayout(grid);
		lbl_MoneyLeftText = new JLabel("Your Money:");
		lbl_MoneyLeft = new JLabel("");
		textField_Raise = new JTextField();
		textField_Raise.setEnabled(!turn);
		lbl_mybettext = new JLabel("Betting:");
		lbl_MyBet = new JLabel("");
		JButton btnRaise = new JButton("Raise");
		btnRaise.setEnabled(!turn);
		
		JButton btnCall = new JButton("Call/Check");
		btnCall.setEnabled(!turn);
		JButton btnFold = new JButton("Fold");
		btnFold.setEnabled(!turn);
		btnFold.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Player player = table.getPlayer();
				player.clearCards();
				guiFuncs.meFold();
				client.sendMessage(new Message(player.getName(),
						CommandType.BET, "-1"));
				setTurn(true);
			}
		});
		Free_Seat_1_me = new JLabel("User seat");
		Free_Seat_1_me.setForeground(Color.GREEN);
		myPanel.add(Free_Seat_1_me);
		myPanel.add(lbl_MoneyLeftText);
		myPanel.add(lbl_MoneyLeft);
		myPanel.add(textField_Raise);
		myPanel.add(new JLabel(""));
		myPanel.add(new JLabel(""));
		myPanel.add(new JLabel(""));
		myPanel.add(lbl_mybettext);
		myPanel.add(lbl_MyBet);
		myPanel.add(btnRaise);
		myPanel.add(btnCall);
		myPanel.add(btnFold);
		//=====================================================================
		//Table panel (INFO)
		//=====================================================================
		Insets insets = new Insets(RIGID,RIGID,RIGID,RIGID);
		JPanel allTable = new JPanel();
		allTable.setLayout(new GridBagLayout());
		tablePanel = new JPanel();
		tablePanel.setLayout(new GridBagLayout());
		GridBagConstraints ce = new GridBagConstraints();
		ce.fill = GridBagConstraints.BOTH;
		tablePanel.setOpaque(false);
		ce.weightx = 0.5;
		ce.insets = insets;
		ce.gridx = 0;
		ce.gridy = 0;
		allTable.add(tablePanel, ce);
		PanelBack back = new PanelBack();
		allTable.add(back, ce);
		GridBagConstraints c = new GridBagConstraints();
		tablePanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
		//***TOP opponent
		//name
		Free_Seat_3 = new JLabel("Free seat");
		c.weightx = 0.5;
		c.insets = insets;
		c.gridx = 2;
		c.gridy = 0;
		tablePanel.add(Free_Seat_3, c);
		//moneyTXT
		lbl_Seat3MoneyText = new JLabel("Money:");
		c.anchor = GridBagConstraints.LINE_START;
		c.gridx = 3;
		c.gridy = 0;
		tablePanel.add(lbl_Seat3MoneyText, c);
		//money
		lbl_Seat3Money = new JLabel("0.0");
		c.anchor = GridBagConstraints.LINE_END;
		c.gridx = 3;
		c.gridy = 0;
		tablePanel.add(lbl_Seat3Money, c);
		//PIC1
		Seat3_kaart_1 = new JLabel();
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 4;
		c.gridy = 0;
		tablePanel.add(Seat3_kaart_1, c);
		Seat3_kaart_1.setIcon(new ImageIcon("src\\Images\\empty.png"));
		//PIC2
		Seat3_kaart_2 = new JLabel();
		c.gridx = 5;
		c.gridy = 0;
		tablePanel.add(Seat3_kaart_2, c);
		Seat3_kaart_2.setIcon(new ImageIcon("src\\Images\\empty.png"));
		
		//***LEFT opponent
		//name
		Free_Seat_2 = new JLabel("Free seat");
		c.anchor = GridBagConstraints.LINE_START;
		c.gridx = 0;
		c.gridy = 0;
		tablePanel.add(Free_Seat_2, c);
		//moneyTXT
		lbl_Seat2MoneyText = new JLabel("Money:");
		c.anchor = GridBagConstraints.LAST_LINE_START;
		c.gridx = 0;
		c.gridy = 0;
		tablePanel.add(lbl_Seat2MoneyText, c);
		//money
		lbl_Seat2Money = new JLabel("0.0");
		c.anchor = GridBagConstraints.LINE_START;
		c.gridx = 0;
		c.gridy = 1;
		tablePanel.add(lbl_Seat2Money, c);
		//PIC1
		Seat2_kaart_1 = new JLabel();
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 0;
		c.gridy = 2;
		tablePanel.add(Seat2_kaart_1, c);
		Seat2_kaart_1.setIcon(new ImageIcon("src\\Images\\empty.png"));
		//PIC2
		Seat2_kaart_2 = new JLabel();
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 0;
		c.gridy = 3;
		tablePanel.add(Seat2_kaart_2, c);
		Seat2_kaart_2.setIcon(new ImageIcon("src\\Images\\empty.png"));
		
		//***Right opponent
		//name
		Free_Seat_4 = new JLabel("Free seat");
		c.anchor = GridBagConstraints.LINE_START;
		c.gridx = 7;
		c.gridy = 0;
		tablePanel.add(Free_Seat_4, c);
		//moneyTXT
		lbl_Seat4MoneyText = new JLabel("Money:");
		c.anchor = GridBagConstraints.LAST_LINE_START;
		c.gridx = 7;
		c.gridy = 0;
		tablePanel.add(lbl_Seat4MoneyText, c);
		//money
		lbl_Seat4Money = new JLabel("0.0");
		c.anchor = GridBagConstraints.LINE_START;
		c.gridx = 7;
		c.gridy = 1;
		tablePanel.add(lbl_Seat4Money, c);
		//PIC1
		Seat4_kaart_1 = new JLabel();
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 7;
		c.gridy = 2;
		tablePanel.add(Seat4_kaart_1, c);
		Seat4_kaart_1.setIcon(new ImageIcon("src\\Images\\empty.png"));
		//PIC2
		Seat4_kaart_2 = new JLabel();
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 7;
		c.gridy = 3;
		tablePanel.add(Seat4_kaart_2, c);
		Seat4_kaart_2.setIcon(new ImageIcon("src\\Images\\empty.png"));
		
		//Table INFO
		//Money txt
		JLabel lbl_TableMoney_Txt = new JLabel("Table:");
		lbl_TableMoney_Txt.setForeground(Color.WHITE);
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 1;
		c.gridy = 1;
		tablePanel.add(lbl_TableMoney_Txt, c);
		//Table money
		lbl_TableBet = new JLabel("");
		lbl_TableBet.setForeground(Color.WHITE);
		c.anchor = GridBagConstraints.PAGE_START;
		c.gridx = 1;
		c.gridy = 2;
		tablePanel.add(lbl_TableBet, c);
		//Table cards
		tbl_Card_1 = new JLabel();
		tbl_Card_2 = new JLabel();
		tbl_Card_3 = new JLabel();
		tbl_Card_4 = new JLabel();
		tbl_Card_5 = new JLabel();
		tableCards.add(tbl_Card_1);
		tableCards.add(tbl_Card_2);
		tableCards.add(tbl_Card_3);
		tableCards.add(tbl_Card_4);
		tableCards.add(tbl_Card_5);

		int i = 2;
		c.anchor = GridBagConstraints.CENTER;
		for (JLabel l : tableCards) {
			c.gridx = i;
			c.gridy = 2;
			tablePanel.add(l, c);
			l.setIcon(new ImageIcon("src\\Images\\empty.png"));
			i++;
		}
		//***MY cards
		//Cards
		//PIC1
		Seat1_kaart_1 = new JLabel();
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 3;
		c.gridy = 4;
		tablePanel.add(Seat1_kaart_1, c);
		Seat1_kaart_1.setIcon(new ImageIcon("src\\Images\\empty.png"));
		//PIC2
		Seat1_kaart_2 = new JLabel();
		c.anchor = GridBagConstraints.CENTER;
		c.gridx = 4;
		c.gridy = 4;
		tablePanel.add(Seat1_kaart_2, c);
		Seat1_kaart_2.setIcon(new ImageIcon("src\\Images\\empty.png"));
		//=====================================================================
		//add table panel
		infoPanel.add(allTable);
		//add my info panel
		infoPanel.add(myPanel);
		//add infopanel
		this.add(scrollPane2, BorderLayout.CENTER);
		
		//=====================================================================
		//Arraylists
		//=====================================================================
		seats.add(Free_Seat_1_me);
		seats.add(Free_Seat_2);
		seats.add(Free_Seat_3);
		seats.add(Free_Seat_4);
		seatCards.add(Seat1_kaart_1); //0
		seatCards.add(Seat1_kaart_2);
		seatCards.add(Seat2_kaart_1); //1
		seatCards.add(Seat2_kaart_2);
		seatCards.add(Seat3_kaart_1); //2
		seatCards.add(Seat3_kaart_2);
		seatCards.add(Seat4_kaart_1); //3
		seatCards.add(Seat4_kaart_2);
		oppMoney.add(lbl_Seat2Money);
		oppMoney.add(lbl_Seat3Money);
		oppMoney.add(lbl_Seat4Money);
		//=====================================================================
		this.guiFuncs = new GUIfuncs(seats, seatCards, tableCards, oppMoney,
				client, textArea, lbl_TableBet,lbl_MoneyLeft, lbl_MyBet, this);
		btnRaise.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				double bet;
				try {
					double maxBet = guiFuncs.getMaxBet() - player.getCurrentBet();
					bet = Math.abs(Double.parseDouble(textField_Raise.getText()));
					if (bet < 0) {
						ErrorWindow ew = new ErrorWindow("Negative bet!", window);
					} else {
						if (bet < maxBet) {
							ErrorWindow ew = new ErrorWindow("You must bet more!", window);
						} else {
							guiFuncs.makeBet(bet);
						}
					}
				} catch(NumberFormatException nfe) {
					ErrorWindow ew = new ErrorWindow("Enter numeric value!", window);
				}
				textField_Raise.setText("");
			}
		});
		btnCall.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				double bet = guiFuncs.getMaxBet() - player.getCurrentBet();
				if (bet < 0) {
					ErrorWindow ew = new ErrorWindow("Negative bet!", window);
				} else {
					guiFuncs.makeBet(bet);
				}
			}
		});
		buttons.add(btnCall);
		buttons.add(btnFold);
		buttons.add(btnRaise);
		
	}
	/**
	 * @param table the table to set
	 */
	public void setTable(Table table) {
		this.table = table;
		this.guiFuncs.setTable(table);
	}
	/**
	 * @param player the player to set
	 */
	public synchronized void setPlayer(Player player) {
		this.player = player;
		this.guiFuncs.setPlayer(player);
		Free_Seat_1_me.setText(player.getName());
		Free_Seat_1_me.setName(player.getName());
		Free_Seat_1_me.setFont(new Font(null, Font.BOLD, 18));
		lbl_MoneyLeft.setText(Double.toString(player.getMoneyLeft()));
	}
	/**
	 * @return the turn
	 */
	public boolean isTurn() {
		synchronized (turnLock) {
			return turn;
		}
	}
	/**
	 * @param turn the turn to set
	 */
	public void setTurn(boolean turn) {
		synchronized (turnLock) {
			for (JButton button : buttons) {
				button.setEnabled(!turn);
			}
			textField_Raise.setEnabled(!turn);
			this.turn = turn;
		}
	}
	/**
	 * @return the window
	 */
	public synchronized Window getWindow() {
		return window;
	}
	/**
	 * Sets client.
	 * @param client Client to set
	 */
	public void setClient(Client client) {
		this.client = client;
		this.guiFuncs.setClient(client);
	}
	/**
	 * @return the guiFuncs
	 */
	public synchronized GUIfuncs getGuiFuncs() {
		return guiFuncs;
	}
	
}
